package com.magnificent.atlantis.client.ui.planner.dialogs.task;

import com.magnificent.atlantis.client.MainLoad;
import com.magnificent.atlantis.client.data.task.TaskHelper;
import com.magnificent.atlantis.client.data.task.common.TaskImportance;
import com.magnificent.atlantis.client.data.task.planner.AbstractPlannerTask;
import com.magnificent.atlantis.client.data.task.planner.BasicPlannerTask;
import com.magnificent.atlantis.client.data.task.planner.CommunityMeetingPlannerTask;
import com.magnificent.atlantis.client.data.task.planner.SimpleMeetingPlannerTask;
import com.magnificent.atlantis.client.ui.common.DependencyTableModel;
import com.magnificent.atlantis.client.ui.common.TaskDialog;
import com.magnificent.atlantis.client.ui.creator.dialogs.DialogConnector;
import com.magnificent.atlantis.client.ui.creator.dialogs.TaskSelectorDialog;
import com.magnificent.atlantis.client.ui.creator.dialogs.TaskType;
import com.magnificent.commons.utils.TimeConstants;
import com.magnificent.commons.utils.collections.CollectionsUtils;

import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * User: Babanin
 * Date: 18.03.2009
 * Time: 15:07:19
 */
public class PlannerTaskDialog extends TaskDialog {

    private boolean edit;

    private AbstractPlannerTask plannerTask;
    private AbstractPlannerTask dependencySelectedPlannerTask;

    private List<AbstractPlannerTask> plannerTaskList;
    private List<AbstractPlannerTask> dependencyPlannerTaskList;
    private PlannerDependencyTableModel plannerDependencyTableModel;

    public PlannerTaskDialog(TaskType taskType, java.util.List<AbstractPlannerTask> plannerTaskList, DialogConnector<Object> dialogConnector) {
        super(MainLoad.getPlannerUI(), taskType, false, dialogConnector, new PlannerDependencyTableModel(new ArrayList<AbstractPlannerTask>()));

        initData(null, plannerTaskList);
    }

    public PlannerTaskDialog(AbstractPlannerTask abstractPlannerTask, List<AbstractPlannerTask> plannerTaskList, DialogConnector<Object> dialogConnector) {
        super(MainLoad.getPlannerUI(),
                abstractPlannerTask instanceof BasicPlannerTask ? TaskType.SIMPLE :
                        abstractPlannerTask instanceof SimpleMeetingPlannerTask ? TaskType.MEETING : TaskType.COMMUNITY_MEETING,
                true, dialogConnector, new PlannerDependencyTableModel(new ArrayList<AbstractPlannerTask>()));

        initData(abstractPlannerTask, plannerTaskList);
    }

    private void initData(AbstractPlannerTask abstractPlannerTask, List<AbstractPlannerTask> plannerTaskList) {
        edit = abstractPlannerTask != null;
        this.plannerTask = abstractPlannerTask != null ? abstractPlannerTask :
                (TaskType.SIMPLE == getTaskType() ? new BasicPlannerTask() :
                        (getTaskType() == TaskType.MEETING ? new SimpleMeetingPlannerTask() :
                                new CommunityMeetingPlannerTask()));

        this.plannerTaskList = plannerTaskList;
        dependencyPlannerTaskList = new ArrayList<AbstractPlannerTask>();
        plannerDependencyTableModel = (PlannerDependencyTableModel) taskTableModel;

        taskCombobox.setModel(new DefaultComboBoxModel(addEmptyElement(this.plannerTaskList.toArray())));
        updateDependencyTextFields(0);

        if (edit) {
            nameTextField.setText(plannerTask.getName());
            descriptionTextArea.setText(plannerTask.getDescription());

            taskCombobox.setModel(new DefaultComboBoxModel(addEmptyElement(onlyPreviousTasks(plannerTaskList, plannerTask.getId()).toArray())));
            taskCombobox.setSelectedIndex(plannerTask.getDependencyTaskId());
            updateDependencyTextFields(plannerTask.getDependencyTaskId());

            long duration = plannerTask.getDuration();
            hourDurationTextField.setText("" + (duration / TimeConstants.MLS_IN_HOUR));
            duration %= TimeConstants.MLS_IN_HOUR;
            minuteDurationTextField.setText("" + (duration / TimeConstants.MLS_IN_MIN));
            
            importanceCombobox.setSelectedItem(plannerTask.getTaskImportance());

            long taskTime = plannerTask.getDependencyTaskTime();
            if (taskTime != 0) {
                dayTextField.setText("" + (taskTime / TimeConstants.MLS_IN_DAY));
                hoursTextField.setText("" + ((taskTime % TimeConstants.MLS_IN_DAY) / TimeConstants.MLS_IN_HOUR));
            }

            dependencyPlannerTaskList = TaskHelper.tasksById(abstractPlannerTask.getDependencyTasks(), plannerTaskList);
            plannerDependencyTableModel.setTasks(dependencyPlannerTaskList);
        } else {
            hourDurationTextField.setText("" + 2);
            minuteDurationTextField.setText("" + 0);
        }
    }

    private List<AbstractPlannerTask> onlyPreviousTasks(List<AbstractPlannerTask> taskList, int id) {
        List<AbstractPlannerTask> result = new ArrayList<AbstractPlannerTask>();

        for (AbstractPlannerTask task : taskList) {
            if (task.getId() < id) {
                result.add(task);
            }
        }

        return result;
    }

    protected Object getTask() {
        return plannerTask;
    }

    protected void addDependencyButtonPressed() {
        final Collection<? extends Object> creatorTasks = CollectionsUtils.exclude(onlyPrevious(PlannerTaskDialog.this.plannerTask), dependencyPlannerTaskList);
        new TaskSelectorDialog(PlannerTaskDialog.this, creatorTasks, new DialogConnector<Object>() {
            public boolean objectSelected(Object obj) {
                dependencyPlannerTaskList.add((AbstractPlannerTask) obj);
                plannerDependencyTableModel.setTasks(dependencyPlannerTaskList);

                return true;
            }
        }).setVisible(true);
    }

    protected void deleteDependencyButtonPressed() {
        dependencyPlannerTaskList.remove(dependencySelectedPlannerTask);
        plannerDependencyTableModel.setTasks(dependencyPlannerTaskList);
        deleteDependencyButton.setEnabled(false);
    }

    protected void dependencyTableSelectionChanged(int selectedRow) {
        if (selectedRow >= 0) {
            dependencySelectedPlannerTask = dependencyPlannerTaskList.get(selectedRow);
            deleteDependencyButton.setEnabled(true);
        } else {
            dependencySelectedPlannerTask = null;
            deleteDependencyButton.setEnabled(false);
        }
    }

    protected boolean checkFields() {
        String name = nameTextField.getText().trim();
        String description = descriptionTextArea.getText().trim();

        if (name.equals("") || description.equals("")) {
            return false;
        }

        if (!edit) {
            plannerTask.setId(plannerTaskList.size() + 1);
        }

        plannerTask.setName(name);
        plannerTask.setDescription(description);

        try {
            plannerTask.setDuration(
                    Integer.parseInt(hourDurationTextField.getText().trim()) * TimeConstants.MLS_IN_HOUR +
                            Integer.parseInt(minuteDurationTextField.getText().trim()) * TimeConstants.MLS_IN_MIN);
        } catch (NumberFormatException nfe) {
            return false;
        }
        
        plannerTask.setTaskImportance((TaskImportance) importanceCombobox.getSelectedItem());
        plannerTask.setDependencyTasks(TaskHelper.getListOfTaskIds(plannerDependencyTableModel));

        if (taskCombobox.getSelectedIndex() > 0) {
            int dependencyTaskId = ((AbstractPlannerTask) taskCombobox.getSelectedItem()).getId();
            try {
                int days = Integer.parseInt(dayTextField.getText().trim());
                int hours = Integer.parseInt(hoursTextField.getText().trim());

                plannerTask.setDependencyTaskId(dependencyTaskId);
                plannerTask.setDependencyTaskTime(TimeConstants.MLS_IN_DAY * days + TimeConstants.MLS_IN_HOUR * hours);

                return true;
            } catch (NumberFormatException nfe) {
                return false;
            }
        } else {
            plannerTask.setDependencyTaskId(-1);
            plannerTask.setDependencyTaskTime(0);
        }


        return true;
    }

    private List<AbstractPlannerTask> onlyPrevious(AbstractPlannerTask plannerTask) {
        if (edit) {
            int taskPos = plannerTaskList.indexOf(plannerTask);

            if (taskPos >= 0) {
                return plannerTaskList.subList(0, taskPos);
            }
        }

        return plannerTaskList;
    }

    public static void createBasicTask(java.util.List<AbstractPlannerTask> plannerTaskList, DialogConnector<Object> dialogConnector) {
        new PlannerTaskDialog(TaskType.SIMPLE, plannerTaskList, dialogConnector).setVisible(true);
    }

    public static void createMeetingTask(java.util.List<AbstractPlannerTask> plannerTaskList, DialogConnector<Object> dialogConnector) {
        new PlannerTaskDialog(TaskType.MEETING, plannerTaskList, dialogConnector).setVisible(true);
    }


    public static void editBasicTask(BasicPlannerTask basicPlannerTask, java.util.List<AbstractPlannerTask> plannerTaskList, DialogConnector<Object> dialogConnector) {
        new PlannerTaskDialog(basicPlannerTask, plannerTaskList, dialogConnector).setVisible(true);
    }

    public static void editMeetingTask(SimpleMeetingPlannerTask meetingPlannerTask, java.util.List<AbstractPlannerTask> plannerTaskList, DialogConnector<Object> dialogConnector) {
        new PlannerTaskDialog(meetingPlannerTask, plannerTaskList, dialogConnector).setVisible(true);
    }

    public static class PlannerDependencyTableModel extends DependencyTableModel<AbstractPlannerTask> {
        public PlannerDependencyTableModel(List<AbstractPlannerTask> plannerTasks) {
            super(plannerTasks);
        }

        public Object getValueAt(int row, int column) {
            AbstractPlannerTask plannerTask = tasks.get(row);

            if (column == 0) {
                return plannerTask.getId();
            }

            return plannerTask.getName();
        }
    }
}
